use std::{fmt, string::FromUtf8Error};

pub type VersionResult<T> = Result<T,VersionError>;

#[derive(Debug)]
pub enum VersionError {
    VcbCreate(sled::Error),
    VcbOpen(std::io::Error),
    DuplicateVersion(String),
    DbError(sled::Error),
}

impl fmt::Display for VersionError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::VcbCreate(e) => write!(f,"Error version contorl block create error:{}",e),
            Self::VcbOpen(e) => write!(f,"Error version control block open error:{}",e),
            Self::DuplicateVersion(version) => write!(f,"Error duplicate version {}",version),
            Self::DbError(e) => write!(f,"sled::Error {}",e),
        }
    }
}

impl std::error::Error for VersionError {}

impl From<std::io::Error> for VersionError {
    fn from(value: std::io::Error) -> Self {
        Self::VcbOpen(value)
    }
}

pub fn vcb_open_error_from(err:sled::Error) -> VersionError {
    VersionError::VcbCreate(err)
}

pub fn db_error_from(err:sled::Error) -> VersionError {
    VersionError::DbError(err)
}

pub type RecipeResult<T> = Result<T,RecipeError>;

#[derive(Debug)]
pub enum RecipeError {
    RecipeWriterOpen(std::io::Error),
    FileWriterOpen(std::io::Error),
    ConWriterOpen(std::io::Error),
    SegWriterOpen(std::io::Error),
    AppendFile(String,std::io::Error),
    AppendCon(u64,std::io::Error),
    AppendPointer(std::io::Error),
    RecipeReaderOpen(std::io::Error),
    FileReaderOpen(std::io::Error),
    ConReaderOpen(std::io::Error),
    SegReaderOpen(std::io::Error),
    GetFile(std::io::Error),
    GetFileName(FromUtf8Error),
    GetCon(std::io::Error),
    GetPointer(std::io::Error),
}

impl fmt::Display for RecipeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::RecipeWriterOpen(e) => write!(f,"recipe writer open error {}",e),
            Self::FileWriterOpen(e) => write!(f,"file writer open error {}",e),
            Self::ConWriterOpen(e) => write!(f,"containerid writer open error {}",e),
            Self::SegWriterOpen(e) => write!(f,"chunk pointer writer open error {}",e),
            Self::AppendFile(file,e) => write!(f,"recipe writer append file {} error {}",file,e),
            Self::AppendCon(no,e) => write!(f,"recipe writer append container {} error {}",no,e),
            Self::AppendPointer(e) => write!(f,"recipe writer append chunk pointer error {}",e),
            Self::RecipeReaderOpen(e) => write!(f,"recipe reader open error {}",e),
            Self::FileReaderOpen(e) => write!(f,"file reader open error {}",e),
            Self::ConReaderOpen(e) => write!(f,"containerid reader open error {}",e),
            Self::SegReaderOpen(e) => write!(f,"chunk pointer reader open error {}",e),
            Self::GetFile(e) => write!(f,"recipe reader get file error {}",e),
            Self::GetFileName(e) => write!(f,"recipe reader get file name error {}",e),
            Self::GetCon(e) => write!(f,"recipe reader get containerid error {}",e),
            Self::GetPointer(e) => write!(f,"recipe reader get chunk pointer error {}",e),
        }
    }
}

impl std::error::Error for RecipeError { }